home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 1.0 for Developers / QuickTime 1.0 for Developers.iso / Programming Stuff / vdig sample / RO364.c < prev    next >
C/C++ Source or Header  |  1991-08-26  |  44KB  |  1,576 lines

  1. /*
  2.     File:        RO364.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    xxx put writers here xxx
  7.  
  8.     Copyright:    © 1991 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     This file is used in these builds: Warhol
  11.  
  12.     Change History (most recent first):
  13.  
  14.         <33>     8/20/91    PH        name changing
  15.         <32>     8/20/91    CK        Add 3 new calls for async multi buffering support (to possibly
  16.                                     replace the current 2 calls), make the component more PAL
  17.                                     friendly in the rect calls and the input calls
  18.         <31>     8/14/91    CK        use new rasterops drvr to 1.3d1, change active rect of stv card
  19.                                     to match the current release (might break early stv cards).
  20.         <30>     7/23/91    MD        fix typo in RegisterComponent
  21.         <29>     7/23/91    JB        Added register component for linked version
  22.         <28>     5/18/91    dvb        Thing->Component
  23.         <27>      5/9/91    PH        only allow 1 thing instance open at a time
  24.         <26>      5/7/91    CK        fix syntax - barfomatic
  25.         <25>      5/7/91    CK        nasty 7.0 bug, no card but have thing in open and close.
  26.         <24>      5/7/91    CK        fix field control flags for 1/2 size requests.
  27.         <23>      5/7/91    PH        base address slime
  28.         <22>      5/6/91    CK        auxbuffer slime bug on main screen fixed.
  29.         <21>      5/6/91    CK        go back to left + 6, last change - ugh!
  30.         <20>      5/6/91    CK        one last tweak to getactiverect.
  31.         <19>      5/6/91    CK        no kludge in getmaxsrcrect since seqgrab is now using
  32.                                     getactiverect.
  33.         <18>      5/5/91    CK        remove SetIdentityMatrix now that we have the register me bit
  34.                                     set (the matrix stuff and toolbox unavailable because open is
  35.                                     called early now)
  36.         <17>      5/5/91    CK        add set and get pllFilterType (for 24stv)
  37.         <16>      5/5/91    CK        move to components.h, use newhandle instead of newhandlesys in
  38.                                     open, remove some unused stuff, add bumpOne for auxbuf
  39.         <15>      5/2/91    CK        Add support for 24STV card, redefine tx, ty calculation with
  40.                                     matrix, fix aux buffer calculation, add 24 STV active rect, init
  41.                                     maxsrc rect global in open
  42.         <14>     4/30/91    CK        Add 5 new source select routines, update to LSC 4.0.4 headers.
  43.         <13>     4/24/91    PH        gnarly hack to fix GetMaxSrcRect
  44.         <12>     4/18/91    MK        fix thing if
  45.         <11>     4/18/91    MK        add storage to close call
  46.         <10>     4/18/91    MK        fix thing if
  47.          <9>     4/17/91    CK        use thing mgr defines for open, close, candoselector, and
  48.                                     getversion; change if to candoselector and getversion due to
  49.                                     thing mgr change
  50.          <8>     4/16/91    CK        Nuke SetMatrix, Fix Poundoff for mpw, make changes due to matrix
  51.                                     changes, remove outdated & unused i/f, remove save state in
  52.                                     playthru, add pmversion to getauxbuf, fill in color stuff, add
  53.                                     version (#8), add async flag, remove outdated .h files
  54.          <7>     3/26/91    CK        add playthru calls, change getmaxauxbuffer interface, allocate
  55.                                     pixmap in globals and dispose in exit, add playthru flag in open
  56.          <6>     2/24/91    CK        Add CanDoSelector and GetVersion calls.
  57.          <5>     2/24/91    CK        Change to make MPW happy, add 2 new mask calls (v1.0d3), change
  58.                                     errors to VideoDigitizerError, add blendLevels to info, ax the
  59.                                     ReleaseAuxBuffer, ax the exact parameter interface.
  60.          <4>     2/23/91    CK        Add new calls (v1.0d3), add vdigType in GetDigitizerInfo, add
  61.                                     exact parameter to SetDigitizerRect, change GetMaskgDevice to
  62.                                     GetMaskPixMap.
  63.          <3>     2/18/91    CK        Add SetIdentity, cleaned up WhackCLUT, removed CheckDestRange,
  64.                                     added AuxBuffer, color control, and GetDigiInfo support, fixed
  65.                                     afew interfaces, added exact parameter, fixed left calculation
  66.                                     in SetDestination, move storage hi before locking
  67.          <2>     2/13/91    CK        Change I/F matrix stuff, add pound off, add 8 bpp 332 color
  68.                                     support
  69.  
  70.     To Do:
  71. */
  72.  
  73. /* RasterOps 364 digitizer wrapper RO364.c */
  74.  
  75. /* 
  76.     File name:     RO364.c 
  77.     Function:    Code file for the RasterOps 364 digitizer wrapper
  78.     History:    1/21/91    New today
  79.                 
  80.     To do:
  81.         1. SetDigitizerRect - Need to add error checking here 
  82. */
  83.  
  84. #include "Slots.h"
  85. #include "Files.h"
  86. #include "Memory.h"
  87. #include "Devices.h"
  88. #include "Resources.h"
  89. #include "ToolUtils.h"
  90. #define FALSE 0
  91. #define TRUE 1
  92. #include "Components.h"
  93. #include "Matrix.h"
  94. #include "video digitizer.h"
  95. #include "RO364.h"
  96. #include "Movies.h"                    /* for kFix1 */
  97.  
  98. /* private prototypes */
  99. pascal long InitRO364Thing(ComponentInstance self);
  100. pascal long ExitRO364Thing(Handle storage,ComponentInstance self);
  101. pascal long CanDoSelector(short selector);
  102. pascal long GetVersion(void);
  103. Boolean GetRefNum(short order, char *slot, short *refnum, Boolean *haveSTV);
  104. Boolean Get24RefNum( char *slot, short *refnum, short *dRefNum, Boolean *haveSTV );
  105. PixMapHandle GetPMap(short refnum, GDHandle *gd);
  106. long CheckAddressRange(Ptr baddr, Ptr ro364BaseAddr);
  107. long CheckDestRect(short top, short left, short *h, short *v, Boolean *needsClip);
  108. pascal void MatrixCopy( MatrixRecord *mfrom, MatrixRecord *mto);
  109. short Pound364HoldOff( short value, GDHandle gdh );
  110. long    PoundSTVHoldOff( short value, short refnum);
  111. pascal void WhackCLUT(short refnum, GDHandle gdh);
  112. pascal void Get332ColorTable(CTabHandle *aCTabHandle);
  113.  
  114. /*#define realthing*/
  115. #ifdef realthing
  116.  
  117. pascal ComponentResult main( ComponentParameters *params, Handle storage )
  118.  
  119. #else
  120. pascal ComponentResult RO364Thing( ComponentParameters *params, Handle storage )
  121.  
  122. #endif
  123.     {
  124.  
  125.     short    selector;
  126.         
  127. /*        Debugger();*/
  128.         selector = params->what;
  129.  
  130.         if (selector < 0) {
  131.             switch (selector) {
  132.                 case kComponentOpenSelect : {
  133.                     return CallComponentFunction(params, InitRO364Thing );
  134.                 }
  135.                 case kComponentCloseSelect : {
  136.                     return  CallComponentFunctionWithStorage(storage, params, ExitRO364Thing);
  137.                 }
  138.                 case kComponentCanDoSelect : {
  139.                     return CallComponentFunction(params, (ComponentFunction)CanDoSelector);
  140.                 }
  141.                 case kComponentVersionSelect : {
  142.                     return CallComponentFunction(params, (ComponentFunction)GetVersion);
  143.                 }
  144.                 default :
  145.                     return (0);
  146.             }
  147.         }
  148.         else {
  149.             switch (selector) {
  150.                 case kSelectVDGrabOneFrameAsync :            
  151.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GrabOneFrameAsync);
  152.                 case kSelectVDGetMaxSrcRect :        
  153.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetMaxSrcRect);
  154.                 case kSelectVDGetActiveSrcRect :    
  155.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetActiveSrcRect);
  156.                 case kSelectVDSetDigitizerRect :    
  157.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetDigitizerRect);
  158.                 case kSelectVDGetDigitizerRect :    
  159.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetDigitizerRect);
  160.                 case kSelectVDGetVBlankRect :        
  161.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetVBlankRect);
  162.                 case kSelectVDDone :                
  163.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)Done);
  164.                 case kSelectVDGetPlayThruDestination :        
  165.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetPlayThruDestination);
  166.                 case kSelectVDSetBrightness :    
  167.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetBrightness);
  168.                 case kSelectVDGetBrightness :    
  169.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetBrightness);
  170.                 case kSelectVDSetContrast :            
  171.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetContrast);
  172.                 case kSelectVDSetHue :                
  173.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetHue);
  174.                 case kSelectVDSetSaturation :        
  175.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetSaturation);
  176.                 case kSelectVDGetContrast :            
  177.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetContrast);
  178.                 case kSelectVDGetHue :                
  179.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetHue);
  180.                 case kSelectVDGetSaturation :        
  181.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetSaturation);
  182.                 case kSelectVDGrabOneFrame :        
  183.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GrabOneFrame);
  184.                 case kSelectVDGetMaxAuxBuffer :        
  185.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetMaxAuxBuffer);
  186.                 case kSelectVDGetDigitizerInfo :    
  187.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetDigitizerInfo);
  188.                 case kSelectVDGetCurrentFlags :        
  189.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetCurrentFlags);
  190.                 case kSelectVDSetPLLFilterType :
  191.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetPLLFilterType);
  192.                 case kSelectVDGetPLLFilterType :
  193.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetPLLFilterType);
  194.                 case kSelectVDSetPlayThruDestination : 
  195.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetPlayThruDestination);
  196.                 case kSelectVDSetPlayThruOnOff : 
  197.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetPlayThruOnOff);
  198.                 case kSelectVDPreflightDestination :         return (digiUnimpErr);
  199.                 case kSelectVDSetBlackLevelValue :
  200.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetBlackLevel);
  201.                 case kSelectVDGetBlackLevelValue :
  202.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetBlackLevel);
  203.                 case kSelectVDSetWhiteLevelValue :
  204.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetWhiteLevel);
  205.                 case kSelectVDGetWhiteLevelValue :
  206.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetWhiteLevel);
  207.                 case kSelectVDGetVideoDefaults : 
  208.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetVideoDefaults);
  209.                 case kSelectVDGetNumberOfInputs : 
  210.                     return CallComponentFunction(params, (ComponentFunction)GetNumberOfInputs);
  211.                 case kSelectVDGetInputFormat : 
  212.                     return CallComponentFunction(params, (ComponentFunction)GetInputFormat);
  213.                 case kSelectVDSetInput : 
  214.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetInput);
  215.                 case kSelectVDGetInput : 
  216.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GetInput);
  217.                 case kSelectVDSetInputStandard : 
  218.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetInputStandard);
  219.                 case kSelectVDSetupBuffers :
  220.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)SetupBuffers);
  221.                 case kSelectVDGrabOneFrameAsync2 :
  222.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)GrabOneFrameAsync2);
  223.                 case kSelectVDDone2 :
  224.                     return CallComponentFunctionWithStorage(storage, params, (ComponentFunction)Done2);
  225.                 default : return (digiUnimpErr);
  226.             }
  227.         };
  228.     }
  229. pascal VideoDigitizerError InitRO364Thing(ComponentInstance self) {
  230. Handle h;
  231. Globals    *g;
  232. char    slot;
  233. short    refnum;
  234. short    dRefnum;
  235. Rect    zeroRect;
  236. GDHandle    gd, savegdh;
  237. Boolean    have364;
  238. unsigned short tSharpness ;    
  239. Boolean     haveSTV;
  240. short    fref;    
  241. long    retstat;
  242.  
  243.     if (CountComponentInstances((Component)self) > 1)
  244.         return(-1);
  245.  
  246. /* allocate some private storage in the system heap and lock it down */
  247.     h = NewHandle(sizeof(Globals));
  248.     MoveHHi(h);
  249.     HLock(h);
  250.  
  251. /* Initialize these fields to somecomponent for now */
  252.     g = (Globals *)(*h);
  253.  
  254.     fref = OpenComponentResFile((Component)self);
  255.     have364 = Get24RefNum(&slot,&refnum, &dRefnum, &haveSTV); 
  256.     CloseComponentResFile(fref);
  257.  
  258. /*    have364 = GetRefNum(1,&slot,&refnum); */
  259.     if (have364) {
  260.     g->haveSTV = haveSTV;
  261.     g->pixMapHndl = GetPMap(dRefnum,&gd);
  262.     g->destPixMapHndl = NewPixMap();
  263.     g->auxBufferPixMapHandle = NewPixMap();
  264.     CopyPixMap(g->pixMapHndl, g->auxBufferPixMapHandle);
  265.     g->refNum = refnum;
  266.     g->gdh = gd;
  267.     g->slot = slot;
  268.     retstat = GetMaxSrcRect(h,ntscIn,&zeroRect);    /* initialize max src rect */
  269.     SetRect(&zeroRect,0,0,0,0);
  270.     g->digiRect = zeroRect;
  271.     g->matrix.matrix[0][0] = kFix1;        /* can't call SetIdentityMatrix at register */
  272.     g->matrix.matrix[1][1] = kFix1;        /* can't call SetIdentityMatrix at register */
  273.     
  274.     
  275.     g->playThruState = vdPlayThruOff;
  276.  
  277.     g->inputFlags =     digiInDoesNTSC | 
  278.                         digiInDoesComposite | 
  279.                         digiInDoesSVideo | 
  280.                         digiInVTR_Broadcast |
  281.                         digiInDoesColor;
  282.  
  283.     g->outputFlags =     digiOutDoes32 |
  284.                         digiOutDoes8 |
  285.                         digiOutDoesShrink |
  286.                         digiOutDoesQuarter |
  287.                         digiOutDoesSixteenth |
  288.                         digiOutDoesHorizFlip |
  289.                         digiOutDoesVertFlip |
  290.                         digiOutDoesHWPlayThru |
  291.                         digiOutDoesAsyncGrabs;
  292.                     
  293.     if (!g->haveSTV) {
  294.         Pound364HoldOff(0,gd);
  295.         }
  296.     else {
  297.         PoundSTVHoldOff(0,g->refNum);
  298.         retstat = SetPLLFilterType(h,vdVTRMode);                /* Default to VTR mode to avoid sync mess with vcr's */
  299.         }
  300.     
  301.     
  302.     SetComponentInstanceStorage(self,h);
  303.     
  304.     GetVideoDefaults(h, &g->blackLevel, &g->whiteLevel, &g->brightness, &g->hue, &g->saturation, &g->contrast, &tSharpness); 
  305.     g->inputSource = compositeIn;
  306.     g->inputStd = ntscIn;
  307.     g->bufferList = 0L;
  308.  
  309. /* for PAL version only */
  310. /*    retstat = SetInputStandard(h,palIn); */
  311.  
  312.     } 
  313.     else {
  314.         DisposHandle(h);
  315.         return (-1);
  316.         }
  317.  
  318.         
  319.     return (0);
  320. }
  321.  
  322. pascal long CanDoSelector(short selector) {
  323. long result = true;
  324.     
  325.     if (selector > kvdigSelectors || selector < kComponentVersionSelect) result = false;
  326.     return (result);
  327. }
  328.  
  329. pascal long GetVersion() {
  330.  
  331.     return ((vdigInterfaceRev<<16) | kCodeRev);        /* interface version in hi word, code rev in lo word  */
  332. }
  333.  
  334. pascal VideoDigitizerError ExitRO364Thing(Handle storage,ComponentInstance self ) {
  335. Globals        *g;
  336. short        error;
  337.  
  338. #pragma unused(self)
  339.  
  340.     if (storage) {
  341.         g = (Globals *)(*storage);
  342.         if (g->haveSTV) error = CloseDriver(g->refNum);
  343.         if (g->bufferList) DisposHandle ((Handle)g->bufferList);
  344.         DisposHandle((Handle)g->destPixMapHndl);
  345.         DisposHandle((Handle)g->auxBufferPixMapHandle);
  346.         DisposHandle(storage);
  347.     }
  348.     return (0);
  349. }
  350.  
  351. pascal VideoDigitizerError    GetMaxSrcRect(Handle storage, short inputStd, Rect *maxSrcRect){
  352. CntrlParam    pb;
  353. Globals        *g;
  354. long        error = noErr;
  355.  
  356.     g = (Globals *)(*storage);
  357.     
  358.     if (g->haveSTV) {
  359.     
  360.         switch (g->inputStd) {
  361.             case ntscIn : case palIn : case secamIn :
  362.                 pb.ioCRefNum = g->refNum;
  363.                 pb.csCode = 9028;
  364.                 error = PBStatus((ParmBlkPtr)&pb,false);
  365.                 *maxSrcRect = *((Rect *)pb.csParam);
  366.                 break;
  367.             default :
  368.                 error = paramErr;
  369.         }
  370.     }
  371.         
  372.     else    if (g->inputStd == ntscIn) {
  373.                 pb.ioCRefNum = g->refNum;
  374.                 pb.csCode = 9028;
  375.                 error = PBStatus((ParmBlkPtr)&pb,false);
  376.                 *maxSrcRect = *((Rect *)pb.csParam);
  377.                 }
  378.             else error = paramErr;
  379.     
  380.     if (!error)g->maxSrcRect = *maxSrcRect;
  381.     
  382.     return (error);
  383.     
  384. }
  385.  
  386. pascal VideoDigitizerError    GetActiveSrcRect(Handle storage, short inputStd, Rect *activeSrcRect){
  387. Globals        *g;
  388. long        error = noErr;
  389.  
  390.         g = (Globals *)(*storage);
  391.  
  392.         if (g->haveSTV) {
  393.         
  394.             switch (g->inputStd) {
  395.                 case ntscIn :
  396.                     activeSrcRect->top = g->maxSrcRect.top + 20;
  397.                     activeSrcRect->left = g->maxSrcRect.left + 54;
  398.                     activeSrcRect->bottom = g->maxSrcRect.bottom - 8;
  399.                     activeSrcRect->right = g->maxSrcRect.right - 7;
  400.             
  401. /*                    activeSrcRect->top = g->maxSrcRect.top + 20;
  402.                     activeSrcRect->left = g->maxSrcRect.left;
  403.                     activeSrcRect->bottom = g->maxSrcRect.bottom - 8;
  404.                     activeSrcRect->right = g->maxSrcRect.right - 76;
  405. */
  406.                     break;
  407.                 
  408.                 case palIn : case secamIn :
  409.                     activeSrcRect->top = g->maxSrcRect.top + 20;
  410.                     activeSrcRect->left = g->maxSrcRect.left + 62;
  411.                     activeSrcRect->bottom = g->maxSrcRect.bottom - 12;
  412.                     activeSrcRect->right = g->maxSrcRect.right - 24;
  413.                     break;
  414.                     
  415.                 default : error = paramErr;
  416.             }
  417.                 
  418.             }
  419.         else     if (g->inputStd == ntscIn) {
  420.                     activeSrcRect->top = g->maxSrcRect.top + 10;
  421.                     activeSrcRect->left = g->maxSrcRect.left + 6;
  422.                     activeSrcRect->bottom = g->maxSrcRect.bottom -10;
  423.                     activeSrcRect->right = g->maxSrcRect.right - 8;
  424.                     }
  425.                 else error = paramErr;
  426.     
  427.         if (!error)g->activeRect = *activeSrcRect;
  428.  
  429.     return (error);
  430. }
  431.  
  432. pascal VideoDigitizerError    GetVBlankRect(Handle storage, short inputStd, Rect *vBlankRect){
  433. Globals        *g;
  434. long        error = noErr;
  435.  
  436.     g = (Globals *)(*storage);
  437.     
  438.     if (g->inputStd == ntscIn || g->inputStd == palIn || g->inputStd == secamIn) {
  439.         g = (Globals *)(*storage);
  440.  
  441.         vBlankRect->top = g->maxSrcRect.top;
  442.         vBlankRect->left = g->maxSrcRect.left + 10;
  443.         vBlankRect->bottom = g->maxSrcRect.top +10;
  444.         vBlankRect->right = g->maxSrcRect.right - 10;
  445.         g->vBlankRect = *vBlankRect;
  446.     }
  447.     else {
  448.         error = paramErr;
  449.     }
  450.     return (error);
  451. }
  452.  
  453. pascal VideoDigitizerError    SetDigitizerRect(Handle storage, Rect *digitizerRect){
  454. Globals     *g;
  455. long        error = noErr;
  456.  
  457. /* SetDigitizerRect - Need to add error checking here */
  458.  
  459.     g = (Globals *)(*storage);
  460.     g->digiRect = *digitizerRect;
  461.     if ((g->digiRect.top % 2) != 0) g->digiRect.top = g->digiRect.top + 1;
  462.     if ((g->digiRect.bottom % 2) != 0) g->digiRect.bottom = g->digiRect.bottom + 1;
  463.         
  464.     return (error);
  465. }
  466.  
  467. pascal VideoDigitizerError    GetDigitizerRect(Handle storage, Rect *digitizerRect){
  468. Globals        *g;
  469. long        error = noErr;
  470.  
  471.     g = (Globals *)(*storage);
  472.     *digitizerRect = g->digiRect;
  473.     
  474.     return (error);
  475.  
  476. }
  477.  
  478. pascal VideoDigitizerError    SetContrast(Handle storage, unsigned short *contrast){
  479. CntrlParam    pb;
  480. Globals        *g;
  481. long        error = noErr;
  482. unsigned short delta;
  483.  
  484.     g = (Globals *)(*storage);
  485.  
  486.     pb.ioCRefNum = g->refNum;
  487.     pb.csCode = 9009;
  488.     pb.csParam[0] = *contrast/1040;
  489.     error = PBControl((ParmBlkPtr)&pb,false);
  490.     if (!error) {
  491.          g->contrast = *contrast;
  492.          delta = *contrast%1040;
  493.          if (delta != 0)
  494.              *contrast = *contrast - delta;
  495.          
  496.     }
  497.     
  498.     return (error);
  499. }        
  500.  
  501. pascal VideoDigitizerError    SetHue(Handle storage, unsigned short *hue){
  502. CntrlParam    pb;
  503. Globals        *g;
  504. long        error = noErr;
  505. unsigned short delta;
  506.  
  507.     g = (Globals *)(*storage);
  508.  
  509.     pb.ioCRefNum = g->refNum;
  510.     pb.csCode = 9006;
  511.     pb.csParam[0] = *hue/1040;
  512.     error = PBControl((ParmBlkPtr)&pb,false);
  513.     if (!error) {
  514.         g->hue = *hue;
  515.         delta = *hue%1040;
  516.         if (delta != 0)
  517.             *hue = *hue - delta;         
  518.     }
  519.     return (error);
  520. }        
  521.  
  522. pascal VideoDigitizerError    SetBrightness(Handle storage, unsigned short *brightness){
  523. CntrlParam    pb;
  524. Globals        *g;
  525. long        error = noErr;
  526. unsigned short delta;
  527.  
  528.     g = (Globals *)(*storage);
  529.  
  530.     pb.ioCRefNum = g->refNum;
  531.     pb.csCode = 9008;
  532.     pb.csParam[0] = *brightness/1040;
  533.     error = PBControl((ParmBlkPtr)&pb,false);
  534.     if (!error) {
  535.         g->brightness = *brightness;
  536.         delta = *brightness%1040;
  537.         if (delta != 0)
  538.             *brightness = *brightness - delta;
  539.          
  540.     }
  541.     return (error);
  542. }        
  543.  
  544. pascal VideoDigitizerError    SetSaturation(Handle storage, unsigned short *saturation){
  545. CntrlParam    pb;
  546. Globals        *g;
  547. long        error = noErr;
  548. unsigned short delta;
  549.  
  550.     g = (Globals *)(*storage);
  551.  
  552.     pb.ioCRefNum = g->refNum;
  553.     pb.csCode = 9007;
  554.     pb.csParam[0] = *saturation/1040;
  555.     error = PBControl((ParmBlkPtr)&pb,false);
  556.     if (!error) {
  557.         g->saturation = *saturation;
  558.         delta = *saturation%1040;
  559.         if (delta != 0)
  560.             *saturation = *saturation - delta;
  561.          
  562.     }
  563.     return (error);
  564. }        
  565. pascal VideoDigitizerError    SetBlackLevel(Handle storage, unsigned short *blackLevel){
  566. CntrlParam    pb;
  567. Globals        *g;
  568. long        error = noErr;
  569. unsigned short delta;
  570.  
  571.     g = (Globals *)(*storage);
  572.  
  573.     pb.ioCRefNum = g->refNum;
  574.     pb.csCode = 9011;
  575.     pb.csParam[0] = *blackLevel/1040;
  576.     error = PBControl((ParmBlkPtr)&pb,false);
  577.     if (!error) {
  578.         g->blackLevel = *blackLevel;
  579.         delta = *blackLevel%1040;
  580.         if (delta != 0)
  581.             *blackLevel = *blackLevel - delta;
  582.          
  583.     }
  584.     return (error);
  585. }        
  586. pascal VideoDigitizerError    SetWhiteLevel(Handle storage, unsigned short *whiteLevel){
  587. CntrlParam    pb;
  588. Globals        *g;
  589. long        error = noErr;
  590. unsigned short delta;
  591.  
  592.     g = (Globals *)(*storage);
  593.  
  594.     pb.ioCRefNum = g->refNum;
  595.     pb.csCode = 9010;
  596.     pb.csParam[0] = *whiteLevel/1040;
  597.     error = PBControl((ParmBlkPtr)&pb,false);
  598.     if (!error) {
  599.         g->whiteLevel = *whiteLevel;
  600.         delta = *whiteLevel%1040;
  601.         if (delta != 0)
  602.             *whiteLevel = *whiteLevel - delta;
  603.          
  604.     }
  605.     return (error);
  606. }        
  607.  
  608. pascal VideoDigitizerError    GetContrast(Handle storage, unsigned short *contrast){
  609. Globals        *g;
  610. long        error = noErr;
  611.  
  612.     g = (Globals *)(*storage);
  613.     *contrast = g->contrast;
  614.     return (error);
  615. }        
  616.  
  617. pascal VideoDigitizerError    GetHue(Handle storage, unsigned short *hue){
  618. Globals        *g;
  619. long        error = noErr;
  620.  
  621.     g = (Globals *)(*storage);
  622.     *hue = g->hue;
  623.     return (error);
  624. }        
  625.  
  626. pascal VideoDigitizerError    GetBrightness(Handle storage, unsigned short *brightness){
  627. Globals        *g;
  628. long        error = noErr;
  629.  
  630.     g = (Globals *)(*storage);
  631.     *brightness = g->brightness;
  632.     return (error);
  633. }        
  634.  
  635. pascal VideoDigitizerError    GetSaturation(Handle storage, unsigned short *saturation){
  636. Globals        *g;
  637. long        error = noErr;
  638.  
  639.     g = (Globals *)(*storage);
  640.     *saturation = g->saturation;
  641.     return (error);
  642. }        
  643.  
  644. pascal VideoDigitizerError    GetBlackLevel(Handle storage, unsigned short *blackLevel){
  645. Globals        *g;
  646. long        error = noErr;
  647.  
  648.     g = (Globals *)(*storage);
  649.     *blackLevel = g->blackLevel;
  650.     return (error);
  651. }        
  652.  
  653. pascal VideoDigitizerError    GetWhiteLevel(Handle storage, unsigned short *whiteLevel){
  654. Globals        *g;
  655. long        error = noErr;
  656.  
  657.     g = (Globals *)(*storage);
  658.     *whiteLevel = g->whiteLevel;
  659.     return (error);
  660. }        
  661.  
  662. pascal VideoDigitizerError    GetVideoDefaults(Handle storage,
  663.                             unsigned short *blackLevel, unsigned short *whiteLevel,
  664.                             unsigned short *brightness, unsigned short *hue, unsigned short *saturation,
  665.                             unsigned short *contrast, unsigned short *sharpness) {
  666. long        error = noErr;
  667.  
  668. /* These values were determined by making status calls to the ro364 driver and recording the defaults */
  669.  
  670.     *blackLevel = 30160;
  671.     *whiteLevel = 58240;
  672.     *brightness = 33280;
  673.     *hue = 33280;
  674.     *saturation = 33280;
  675.     *contrast = 33280;
  676.     *sharpness = 0;
  677.     
  678.     return (error);
  679. }        
  680.  
  681. pascal VideoDigitizerError    GrabOneFrame(Handle storage){
  682. CntrlParam    pb;
  683. Globals        *g;
  684. long        error = noErr;
  685. long        count;
  686. OSErr        ioresult;
  687.  
  688.     g = (Globals *)(*storage);
  689.     g->gpb.ioCompletion = 0;
  690.     g->gpb.ioCRefNum = g->refNum;
  691.     g->gpb.csCode = 9026;
  692.     g->gpb.csParam[0] = 1;
  693.     error = PBControl((ParmBlkPtr)&g->gpb,false);
  694.     return (error);
  695. }        
  696.  
  697. pascal VideoDigitizerError    GetMaxAuxBuffer(Handle storage, PixMapHandle *pm, Rect *rect){
  698. Globals        *g;
  699. long        error = noErr;
  700. short        hVisable, vVisable;
  701.  
  702.     g = (Globals *)(*storage);
  703.     
  704.     *pm = g->auxBufferPixMapHandle;
  705.     hVisable = (**(*g).pixMapHndl).bounds.right - (**(*g).pixMapHndl).bounds.left;
  706.     if ((**(*g).pixMapHndl).pixelSize == 32) {    
  707.         (***pm).baseAddr = (**(*g).pixMapHndl).baseAddr + ((**(*g).pixMapHndl).pixelSize/8 * hVisable);
  708.         (***pm).pmVersion = 4;                /* sure it's 32 bit clean */
  709.         }
  710.     else if ((**(*g).pixMapHndl).pixelSize == 8) {
  711.         (***pm).baseAddr = (**(*g).pixMapHndl).baseAddr  + (long)hVisable;    
  712.         (***pm).pmVersion = 4;                /* sure it's 32 bit clean */
  713.         }
  714.     else error = badDepth;    
  715.         
  716.     SetRect(&(***pm).bounds,0,0,383,510);                    /* size of ro364 in 24 bpp */
  717.     SetRect(rect,0,0,383,510);                            /* size of ro364 in 24 bpp */
  718.  
  719.     return (error);
  720. }        
  721.  
  722. pascal VideoDigitizerError    GetDigitizerInfo(Handle storage, DigitizerInfo *info){
  723. Globals        *g;
  724. long        error = noErr;
  725. long        in, out;
  726.  
  727.     g = (Globals *)(*storage);
  728.     
  729.     info->vdigType = vdTypeBasic;
  730.     info->inputCapabilityFlags = g->inputFlags;
  731.     info->outputCapabilityFlags = g->outputFlags;
  732.     error = GetCurrentFlags(storage, &in, &out);
  733.     info->inputCurrentFlags = in;
  734.     info->outputCurrentFlags = out;
  735.     info->slot = g->slot;
  736.     info->gdh =  g->gdh;
  737.     info->minDestHeight = 0;
  738.     info->minDestWidth = 0;
  739.     info->maxDestHeight = g->maxSrcRect.bottom - g->maxSrcRect.top;
  740.     info->maxDestWidth = g->maxSrcRect.right - g->maxSrcRect.left;
  741.     info->blendLevels = 0;
  742.     return (error);
  743. }        
  744.  
  745. pascal VideoDigitizerError    GetCurrentFlags(Handle storage, long *inputCurrentFlag, long *outputCurrentFlag) {
  746. CntrlParam    pb;
  747. Globals        *g;
  748. long        error = noErr;
  749.  
  750.     g = (Globals *)(*storage);
  751.  
  752. /* Get the current input flag information */    
  753.     pb.ioCRefNum = g->refNum;
  754.     pb.csCode = 9005;
  755.     error = PBStatus((ParmBlkPtr)&pb,false);
  756.     if (pb.csParam[0] == 0) {
  757.         *inputCurrentFlag = 0;                /* nothing there */
  758.     }
  759.     else {
  760.         *inputCurrentFlag = digiInDoesNTSC | digiInSignalLock;
  761.         if (pb.csParam[1] == 0) 
  762.             *inputCurrentFlag = *inputCurrentFlag | digiInDoesComposite;
  763.         else
  764.             *inputCurrentFlag = *inputCurrentFlag | digiInDoesSVideo;
  765.     }
  766.  
  767. /* Get the current output flag information */
  768. /*   - Currently support pixelSize, shrink, flips only */    
  769.     *outputCurrentFlag = 0;
  770.     if ((**(*g).pixMapHndl).pixelSize == 32) {
  771.         *outputCurrentFlag = *outputCurrentFlag | digiOutDoes32;
  772.     }
  773.     else if ((**(*g).pixMapHndl).pixelSize == 8) {
  774.         *outputCurrentFlag = *outputCurrentFlag | digiOutDoes8;
  775.     }
  776.     else return (error);
  777.     
  778.     if (g->matrix.matrix[1][1] < 0) *outputCurrentFlag = *outputCurrentFlag | digiOutDoesVertFlip;
  779.     if (g->matrix.matrix[0][0] < 0) *outputCurrentFlag = *outputCurrentFlag | digiOutDoesHorizFlip;
  780.     if ((FixRound(g->matrix.matrix[0][0]) != 1) || (FixRound(g->matrix.matrix[0][0]) != 1))
  781.         *outputCurrentFlag = *outputCurrentFlag | digiOutDoesShrink;
  782.     
  783.     return (error);
  784. }        
  785.  
  786.  
  787. pascal VideoDigitizerError    SetPLLFilterType(Handle storage, short pllType) {
  788. CntrlParam    pb;
  789. Globals        *g;
  790. long        error = noErr;
  791.  
  792.     g = (Globals *)(*storage);
  793.  
  794.     pb.ioCRefNum = g->refNum;
  795.     pb.csCode = 9034;
  796.     pb.csParam[0] = pllType;
  797.     error = PBControl((ParmBlkPtr)&pb,false);
  798.     return (error);
  799.  
  800. }
  801. pascal VideoDigitizerError    GetPLLFilterType(Handle storage, short *pllType) {
  802. CntrlParam    pb;
  803. Globals        *g;
  804. long        error = noErr;
  805.  
  806.     g = (Globals *)(*storage);
  807.  
  808.     pb.ioCRefNum = g->refNum;
  809.     pb.csCode = 9034;
  810.     error = PBStatus((ParmBlkPtr)&pb,false);
  811.     *pllType = pb.csParam[0];
  812.  
  813.     return (error);
  814. }    
  815.  
  816. pascal VideoDigitizerError    SetPlayThruDestination(Handle storage, PixMapHandle dest, Rect *destRect, MatrixRecord *m, RgnHandle mask) {
  817.  
  818. CntrlParam    pb;
  819. Globals        *g;
  820. long        error = noErr;
  821.  
  822. Ptr            ro364BaseAddr;
  823. short        ro364RowBytes;
  824. short        top, left;
  825.  
  826. short        hreq, vreq, h1, w1;
  827. short        savehreq, savevreq;
  828. short        tx, ty;
  829.  
  830. Boolean        hFlip = FALSE;
  831. Boolean        vFlip = FALSE;
  832. Boolean        needsClip = FALSE;
  833.  
  834. long        lvreq;
  835.  
  836. Ptr        baddr;
  837. short    rowBytes;
  838. short    pixelSize;
  839.  
  840.  
  841.     g = (Globals *)(*storage);
  842.     
  843.     ro364BaseAddr = (**(*g).pixMapHndl).baseAddr;
  844.     ro364RowBytes = (**(*g).pixMapHndl).rowBytes & 0x7FFF;        /* clear high bit set by QD */
  845.  
  846.     baddr = (**dest).baseAddr;
  847.     rowBytes = (**dest).rowBytes & 0x7FFF;
  848.     pixelSize = (**dest).pixelSize;
  849.     
  850. /* We have to calculate the following stuff before the test to do scaling in case the dest rect needs clipping
  851.     in the translation section.
  852. */
  853.     h1 = g->digiRect.bottom - g->digiRect.top;                    /* get the current full size height */
  854.     w1 = g->digiRect.right - g->digiRect.left;                    /* get the current full size width */
  855.  
  856.     if (m == 0) {
  857.         vreq = destRect->bottom - destRect->top;
  858.         hreq = destRect->right - destRect->left;
  859.         tx = destRect->left - (*dest)->bounds.left;
  860.         ty = destRect->top - (*dest)->bounds.top;
  861.         vFlip = FALSE;
  862.         hFlip = FALSE;
  863.         }
  864.     else {
  865.         vreq = FixRound(FixMul( (FixRatio(h1,1)),(m->matrix)[1][1]));    /* calculate the scaled height */
  866.         hreq = FixRound(FixMul( (FixRatio(w1,1)),(m->matrix)[0][0])); /* calculate the scaled width */
  867.         tx = FixRound( (m->matrix)[2][0]) - (*dest)->bounds.left;
  868.         ty = FixRound( (m->matrix)[2][1]) - (*dest)->bounds.top;
  869.         vFlip = ( ((m->matrix)[1][1] < 0) ^ (g->matrix.matrix[1][1] < 0) );
  870.         hFlip = ( ((m->matrix)[0][0] < 0) ^ (g->matrix.matrix[0][0] < 0) );
  871.         if (vreq < 0) vreq = -vreq;
  872.         if (hreq < 0) hreq = -hreq;
  873.     }
  874.  
  875.     if ((vreq % 2) != 0) vreq = vreq + 1;                        /* special adjustment for RO364 */
  876. /* If vreq is adjusted, then a new Sy really needs to be computed (Use CalculateScale), 
  877.     stored in the matrix and the notExactMatrix warning set.
  878. */
  879.  
  880. /* Do the scaling (only if the scale coefficients have changed */
  881. /* This is currently commented out because it won't work right if the digiRect was clipped then unclipped */
  882. /*    if (((*matrix)[0][0] != (g->matrix)[0][0]) || ((*matrix)[1][1] != (g->matrix)[1][1])) { */
  883.         pb.ioCRefNum = g->refNum;
  884.         pb.csCode = 9012;
  885.     
  886.         pb.csParam[0] = g->digiRect.top;
  887.         pb.csParam[1] = g->digiRect.left;
  888.         pb.csParam[2] = g->digiRect.bottom;
  889.         pb.csParam[3] = g->digiRect.right;
  890.         pb.csParam[4] = hreq;
  891.         pb.csParam[5] = vreq;
  892.     
  893.         if ((hreq <= 640/2) && (vreq <= 480/2)) {
  894.             if (g->haveSTV) pb.csParam[6] = 5;
  895.             else pb.csParam[6] = 2;                            /* use even field for 1/2 size or less */
  896.         }
  897.         else {
  898.             pb.csParam[6] = 0;                            /* use both fields for greater than 1/2 size */
  899.         }
  900.     
  901.         error = PBControl((ParmBlkPtr)&pb,false);
  902. /*    } */
  903.  
  904. /* Do the translation */    
  905.  
  906.     if (baddr == nil) {
  907.         pb.csParam[0] = ty;
  908.         pb.csParam[1] = tx;
  909.     }
  910.     else {
  911.     
  912.         if ((pixelSize != 32) && (pixelSize != 8)) error = badDepth;
  913. /*        if ((pixelSize != 32) || ((**(*g).pixMapHndl).pixelSize != 32)) error = badDepth; */
  914. /*        if (pixelSize == 8 && pixelSize != g->pixelSize) WhackCLUT(g->refNum,g->gdh); */
  915.  
  916.         if (pixelSize == 8) WhackCLUT(g->refNum,g->gdh);
  917.         
  918.         if (error == 0) error = CheckAddressRange(baddr, ro364BaseAddr);        /* make sure it's my screen */
  919.         
  920.         if (error == 0) {
  921.             top = (baddr - ro364BaseAddr)/(ro364RowBytes);
  922.             if (pixelSize == 32)
  923.                 left = ((baddr - ro364BaseAddr)/4)%(ro364RowBytes/4);
  924.             else
  925.                 left = (baddr - ro364BaseAddr)%(ro364RowBytes);
  926.             top = top + ty;
  927.             left = left + tx;
  928.             savehreq = hreq;
  929.             savevreq = vreq;
  930.             error = CheckDestRect(top,left, &hreq, &vreq, &needsClip);
  931.             
  932.             if (needsClip) {
  933.                 lvreq = (long)vreq * (long)(g->digiRect.bottom - g->digiRect.top);
  934.                 lvreq = lvreq / (long)savevreq;
  935.                 savevreq = vreq; 
  936.                 if ((savevreq % 2) != 0) savevreq = savevreq + 1;                        /* special adjustment for RO364 */
  937.                 vreq = lvreq;
  938.                 if ((vreq % 2) != 0) vreq = vreq + 1;                                    /* special adjustment for RO364 */
  939.                 pb.ioCRefNum = g->refNum;
  940.                 pb.csCode = 9012;
  941.     
  942.                 pb.csParam[0] = g->digiRect.top;
  943.                 pb.csParam[1] = g->digiRect.left;
  944.                 pb.csParam[2] = g->digiRect.top + vreq;
  945.                 pb.csParam[3] = g->digiRect.right;
  946.                 pb.csParam[4] = savehreq;
  947.                 pb.csParam[5] = savevreq;
  948.     
  949.                 if ((hreq <= 654/2) && (vreq <= 510/2)) {
  950.                     pb.csParam[6] = 2;                            /* use even field for 1/2 size or less */
  951.                 }
  952.                 else {
  953.                     pb.csParam[6] = 0;                            /* use both fields for greater than 1/2 size */
  954.                 }
  955.     
  956.                 error = PBControl((ParmBlkPtr)&pb,false);
  957.             
  958.             }
  959.         }
  960.         
  961.         if (error == 0) {
  962.             g->bumpOne = false;
  963.             if ((top % 2) != 0) {
  964.                 top = top + 1;
  965.                 g->bumpOne = true;
  966.             }
  967.             pb.csParam[0] = top;
  968.             pb.csParam[1] = left;
  969.         }
  970.     }
  971.     pb.ioCRefNum = g->refNum;
  972.     pb.csCode = 9015;
  973.  
  974.     if (error == 0) error = PBControl((ParmBlkPtr)&pb,false);
  975.  
  976. /* Do any flipping special effects */
  977.  
  978.     if (hFlip) {
  979.         pb.ioCRefNum = g->refNum;
  980.         pb.csCode = 9028;
  981.         if (error == 0) error = PBControl((ParmBlkPtr)&pb,false);
  982.     }
  983.     if (vFlip) {
  984.         pb.ioCRefNum = g->refNum;
  985.         pb.csCode = 9029;
  986.         if (error == 0) error = PBControl((ParmBlkPtr)&pb,false);
  987.     }
  988. /*** Add other fields to globals here ****/
  989.     if (!error) {
  990.         CopyPixMap(dest,g->destPixMapHndl); 
  991.         g->destRect = *destRect; 
  992.         }
  993.     MatrixCopy(m,&(g->matrix)); 
  994.     g->baddr = ro364BaseAddr;
  995.     g->rowBytes = rowBytes;
  996.     g->pixelSize = pixelSize;
  997.     g->top = top;
  998.     g->left = left;
  999.  
  1000. /* Save the params for the next time through */
  1001.  
  1002.     g->nextDest = 0;
  1003.     
  1004.     return (error);
  1005. }
  1006.  
  1007. pascal VideoDigitizerError    SetPlayThruOnOff(Handle storage, short state)
  1008. {
  1009. CntrlParam    pb;
  1010. Globals        *g;
  1011. long        error = noErr;
  1012.  
  1013.     g = (Globals *)(*storage);
  1014.     pb.ioCRefNum = g->refNum;
  1015.     
  1016.     pb.csCode = 9024;
  1017.     pb.csParam[0] = 1;                    /* Always do full speed */
  1018.     error = PBControl((ParmBlkPtr)&pb,false);
  1019.  
  1020.     if (!error) {
  1021.         pb.csCode = 9025;
  1022.     
  1023.         switch (state) {
  1024.             case vdPlayThruOn : {
  1025.                 pb.csParam[0] = 1;
  1026.                 break;
  1027.             }
  1028.             case vdPlayThruOff : {
  1029.                 pb.csParam[0] = 0;
  1030.                 break;
  1031.             }
  1032.             default : {
  1033.                 return (paramErr);
  1034.             }
  1035.         }
  1036.         pb.csParam[1] = 1;                /* Always wait for now */
  1037.     
  1038.         error = PBControl((ParmBlkPtr)&pb,false);
  1039.     }
  1040.     if (!error)g->playThruState = state;
  1041.     return (error);
  1042.  
  1043.  
  1044. }        
  1045.  
  1046. pascal VideoDigitizerError    GetPlayThruDestination(Handle storage, PixMapHandle *dest, Rect *destRect,
  1047.                                 MatrixRecord *m, RgnHandle *mask) {
  1048. Globals        *g;
  1049. long        error = 0;
  1050.  
  1051.     g = (Globals *)(*storage);
  1052.     
  1053.     CopyPixMap(g->destPixMapHndl,*dest);
  1054.     *destRect = g->destRect;
  1055.     MatrixCopy(&(g->matrix),m);
  1056.     *mask = 0L;
  1057.     
  1058.     return (error);
  1059. }        
  1060.  
  1061. pascal VideoDigitizerError    GrabOneFrameAsync(Handle storage, Boolean bufferingOn, PixMapHandle nextDest, Point nextDestPt) {
  1062. Globals        *g;
  1063. long        error = 0;
  1064. Ptr            baddr;
  1065. short        t, l;
  1066. CntrlParam    pb;
  1067.  
  1068.     g = (Globals *)(*storage);
  1069.     
  1070.     if (bufferingOn) {
  1071.         if (g->nextDest == 0) {
  1072.             t = g->top;
  1073.             l = g->left;
  1074.         }
  1075.         else {
  1076.             baddr = (**g->nextDest).baseAddr;
  1077.             t = (baddr - g->baddr)/(g->rowBytes) + (g->nextDestPt.v - (*g->nextDest)->bounds.top);
  1078.             if (g->bumpOne) t += 1;                    /* slime for ro364 card to stop wiggle ??? */
  1079.             if ((t % 2) != 0) t = t + 1;
  1080.             if (g->pixelSize == 32)
  1081.                 l = ((baddr - g->baddr)/4)%(g->rowBytes/4) + (g->nextDestPt.h - (*g->nextDest)->bounds.left);
  1082.             else
  1083.                 l = (baddr - g->baddr)%(g->rowBytes) + (g->nextDestPt.h - (*g->nextDest)->bounds.left);
  1084.         }
  1085.     
  1086.         g->gpb.csParam[0] = t;
  1087.         g->gpb.csParam[1] = l;
  1088.         g->gpb.ioCRefNum = g->refNum;
  1089.         g->gpb.csCode = 9015;
  1090.         error = PBControl((ParmBlkPtr)&g->gpb,false);
  1091.     }
  1092.  
  1093. /* Do the async frame grab */
  1094.     g->gpb.ioCompletion = 0;
  1095.     g->gpb.ioCRefNum = g->refNum;
  1096.     g->gpb.csCode = 9026;
  1097.     g->gpb.csParam[0] = 0;
  1098.     error = PBControl((ParmBlkPtr)&g->gpb,true);
  1099.     
  1100. /* Save the params for the next time through */
  1101.  
  1102.     g->nextDest = nextDest;
  1103.     g->nextDestPt = nextDestPt;
  1104.  
  1105.     return (error);
  1106. }
  1107.  
  1108. pascal long Done(Handle storage) {
  1109. long retstat;
  1110. long    error;
  1111. Globals        *g;
  1112. CntrlParam    pb;
  1113.  
  1114.     retstat = false;
  1115.     g = (Globals *)(*storage);
  1116.     
  1117.     pb.ioCompletion = 0;
  1118.     pb.ioCRefNum = g->refNum;
  1119.     pb.csCode = 9026;
  1120.     error = PBStatus((ParmBlkPtr)&pb,false);
  1121.     
  1122.     if (pb.csParam[0] == 0) retstat = true;
  1123.     
  1124.     return (retstat);
  1125. }
  1126.     
  1127. pascal VideoDigitizerError    GetNumberOfInputs(short *inputs) {
  1128. long        error = noErr;
  1129.  
  1130.     *inputs = 2;
  1131.     return (error);
  1132. }        
  1133.  
  1134. pascal VideoDigitizerError    GetInputFormat(short input, short *format) {
  1135. long        error = noErr;
  1136.     switch (input) {
  1137.         case 0 : {
  1138.             *format = compositeIn;
  1139.             break;
  1140.         }
  1141.         case 1 : {
  1142.             *format = sVideoIn;
  1143.             break;
  1144.         }
  1145.         default : {
  1146.             return (paramErr);
  1147.         }
  1148.     }
  1149.     return (error);
  1150. }
  1151. pascal VideoDigitizerError    SetInput(Handle storage, short input){
  1152. long    error = noErr;
  1153. Globals        *g;
  1154. CntrlParam    pb;
  1155.  
  1156.     g = (Globals *)(*storage);
  1157.     
  1158.     pb.ioCRefNum = g->refNum;
  1159.     pb.csCode = 9005;
  1160.     pb.csParam[0] = input;
  1161.     error = PBControl((ParmBlkPtr)&pb,false);
  1162.     
  1163.     if (!error) g->inputSource = input;
  1164.     return (error);
  1165. }
  1166.  
  1167. pascal VideoDigitizerError    GetInput(Handle storage, short *input){
  1168. long    error = noErr;
  1169. Globals        *g;
  1170.  
  1171.     g = (Globals *)(*storage);
  1172.     *input = g->inputSource;
  1173.     return (error);
  1174. }
  1175.  
  1176. pascal VideoDigitizerError    SetInputStandard(Handle storage, short inputStandard){
  1177. long    error = noErr;
  1178. Globals        *g;
  1179. CntrlParam    pb;
  1180.  
  1181.     g = (Globals *)(*storage);
  1182.     
  1183.     pb.ioCRefNum = g->refNum;
  1184.     pb.csCode = 9038;
  1185.     
  1186.     switch (inputStandard) {
  1187.         case ntscIn : 
  1188.             pb.csParam[0] = 0;
  1189.             break;
  1190.         case palIn : 
  1191.             pb.csParam[0] = 1;
  1192.             break;
  1193.         case secamIn :
  1194.             pb.csParam[0] = 2;
  1195.             break;
  1196.         case autoDetectIn :
  1197.             error = paramErr;
  1198.             break;
  1199.     }
  1200.     
  1201.     if (!error) g->inputStd = inputStandard;
  1202.                 
  1203.     error = PBControl((ParmBlkPtr)&pb,false);
  1204.     return (error);
  1205. }
  1206.  
  1207. pascal VideoDigitizerError    SetupBuffers(Handle storage, VdigBufferRecListHandle bufferList){
  1208. long    error = noErr;
  1209. Globals        *g;
  1210. short    i;
  1211. PixMapHandle    theDest;
  1212. Point            thePoint;
  1213. Ptr                baddr;
  1214. short            t, l;
  1215.  
  1216.     g = (Globals *)(*storage);
  1217.     if (!g->bufferList) {
  1218.         g->bufferList = (VdigBufferLocalListHandle)NewHandle( sizeof(VdigBufferLocalList) +
  1219.                             (**bufferList).count * sizeof(VdigBufferLocal));
  1220.     }
  1221.     else {
  1222.         DisposHandle((Handle)g->bufferList);
  1223.         g->bufferList = (VdigBufferLocalListHandle)NewHandle( sizeof(VdigBufferLocalList) +
  1224.                             (**bufferList).count * sizeof(VdigBufferLocal));
  1225.     }
  1226.     
  1227.     (**g->bufferList).count = (**bufferList).count;
  1228.     for (i=0; i<(**bufferList).count; i++) {
  1229.     
  1230.         theDest = (**bufferList).list[i].dest;
  1231.         baddr = (**theDest).baseAddr;
  1232.         thePoint = (**bufferList).list[i].location;
  1233.     
  1234.         t = (**g->bufferList).list[i].top = (baddr - g->baddr)/(g->rowBytes) + (thePoint.v - (*theDest)->bounds.top);
  1235.         if (g->bumpOne) (**g->bufferList).list[i].top += 1;
  1236.         if (((**g->bufferList).list[i].top % 2) != 0) (**g->bufferList).list[i].top += 1;
  1237.         if (g->pixelSize == 32)
  1238.             l = (**g->bufferList).list[i].left = ((baddr - g->baddr)/4)%(g->rowBytes/4) + (thePoint.h - (*theDest)->bounds.left);
  1239.         else
  1240.             l = (**g->bufferList).list[i].left = (baddr - g->baddr)%(g->rowBytes/4) + (thePoint.h - (*theDest)->bounds.left);
  1241.         
  1242.         (**g->bufferList).list[i].pixelSize = g->pixelSize;        
  1243.         (**g->bufferList).list[i].doneState = FALSE;        
  1244.         
  1245.         /* validate the destinations */
  1246.         
  1247.     }
  1248.  
  1249.     return (error);
  1250. }
  1251.  
  1252. pascal VideoDigitizerError    GrabOneFrameAsync2(Handle storage, short buffer) {
  1253. Globals        *g;
  1254. long        error = 0;
  1255. CntrlParam    pb;
  1256. short        prevBuffer;
  1257.  
  1258.     g = (Globals *)(*storage);
  1259.  
  1260. /* Do the move */
  1261.     g->gpb.csParam[0] = (**g->bufferList).list[buffer].top;
  1262.     g->gpb.csParam[1] = (**g->bufferList).list[buffer].left;
  1263.     g->gpb.ioCRefNum = g->refNum;
  1264.     g->gpb.csCode = 9015;
  1265.     error = PBControl((ParmBlkPtr)&g->gpb,false); 
  1266.  
  1267. /* Do the async frame grab */
  1268.     g->gpb.ioCompletion = 0;
  1269.     g->gpb.ioCRefNum = g->refNum;
  1270.     g->gpb.csCode = 9026;
  1271.     g->gpb.csParam[0] = 0;
  1272.     if (!error) error = PBControl((ParmBlkPtr)&g->gpb,true); 
  1273.     
  1274.     prevBuffer = buffer - 1;
  1275.     if (prevBuffer < 0) prevBuffer = (**g->bufferList).count - 1;
  1276.     
  1277. /* we assume that the previous buffer is done especially since the move must wait
  1278.     for frame complete */
  1279.     
  1280.     (**g->bufferList).list[prevBuffer].doneState = TRUE;    /* just a guess */
  1281.     (**g->bufferList).list[buffer].doneState = FALSE;        /* current frame is not done yet */
  1282.  
  1283.     return(error);
  1284. }
  1285.     
  1286. pascal long    Done2(Handle storage, short buffer) {
  1287. Globals        *g;
  1288. long        retstat;
  1289.     
  1290.     retstat = FALSE;
  1291.     g = (Globals *)(*storage);
  1292.     if ((**g->bufferList).list[buffer].doneState) retstat = TRUE;
  1293.     if (!retstat) retstat = Done(storage); /* just in case it's the last one */
  1294.     return ( retstat );
  1295. }
  1296.  
  1297.     
  1298. /* Utilities */
  1299.  
  1300. Boolean GetRefNum(short order, char *slot, short *refnum, Boolean *haveSTV)
  1301. {
  1302. SpBlock    mySpBlock;
  1303. short    count;
  1304. Boolean    retstat = FALSE;
  1305.  
  1306.     *refnum = 0;
  1307.     mySpBlock.spSlot = 0;
  1308.     mySpBlock.spID = 0;
  1309.     mySpBlock.spExtDev = 0;
  1310.     mySpBlock.spHwDev = 0;
  1311.     mySpBlock.spTBMask = 0x000E;            /* only key on spDrvrHW */
  1312.     mySpBlock.spDrvrHW = 0x2AD;                /* assigned driver hw id */
  1313.  
  1314.     count = 0;
  1315.     while (!SNextTypeSRsrc(&mySpBlock))
  1316.     {
  1317.         count++;
  1318.         if (order == count)
  1319.         {
  1320.             *refnum = mySpBlock.spRefNum;
  1321.             *slot = mySpBlock.spSlot;
  1322.             retstat = TRUE;
  1323.             *haveSTV = TRUE;
  1324.             break;
  1325.         }
  1326.     }
  1327.     
  1328.     if (!retstat) {        /* no ro24stv so look for ro364 */
  1329.         *refnum = 0;
  1330.         mySpBlock.spSlot = 0;
  1331.         mySpBlock.spID = 0;
  1332.         mySpBlock.spExtDev = 0;
  1333.         mySpBlock.spHwDev = 0;
  1334.         mySpBlock.spTBMask = 0x000E;            /* only key on spDrvrHW */
  1335.         mySpBlock.spDrvrHW = 0x26F;                /* assigned driver hw id */
  1336.  
  1337.         count = 0;
  1338.         while (!SNextTypeSRsrc(&mySpBlock))
  1339.         {
  1340.             count++;
  1341.             if (order == count)
  1342.             {
  1343.                 *refnum = mySpBlock.spRefNum;
  1344.                 *slot = mySpBlock.spSlot;
  1345.                 retstat = TRUE;
  1346.                 *haveSTV = FALSE;
  1347.                 break;
  1348.             }
  1349.         }
  1350.     }
  1351.     return (retstat);
  1352. }
  1353. Boolean Get24RefNum( char *slot, short *refnum, short *dRefNum, Boolean *haveSTV )
  1354. {
  1355. Boolean        valid = false;
  1356. OSErr        error = noErr;
  1357. CntrlParam    pb;
  1358. short        count;
  1359. Handle         r;
  1360.  
  1361.     valid = GetRefNum( 1, slot, dRefNum, haveSTV);  
  1362.     
  1363.     if (valid) {
  1364.         if (*haveSTV) {
  1365.             error = OpenDriver ( "\p.RasterOps24STVPIP1.3d1", refnum ); 
  1366.             r = GetNamedResource('DRVR', "\p.RasterOps24STVPIP1.3d1");
  1367.             DetachResource(r); 
  1368.             HNoPurge(r);
  1369.     
  1370.             if (error == noErr)
  1371.             {
  1372.                 pb.ioCRefNum = *refnum;
  1373.                 pb.csCode = 9027;                /* reset */
  1374.                 if ((error = PBControl((ParmBlkPtr)&pb,false))==noErr)
  1375.                 {
  1376.                     pb.ioCRefNum = *refnum;
  1377.                     pb.csCode = 9005;
  1378.                     pb.csParam[0] = 0;            /* 0 = composite    1 = s video */
  1379.                     error = PBControl((ParmBlkPtr)&pb,false);
  1380.                 }
  1381.             }
  1382.         }
  1383.         else {
  1384.             *refnum = *dRefNum;                    /* only one driver for the ro364 */
  1385.         }
  1386.     }
  1387.         
  1388.     return (valid & !error);
  1389. }
  1390.  
  1391.  
  1392.  
  1393. PixMapHandle GetPMap(short refnum, GDHandle *gdhdl) {
  1394. GDHandle    gdh;
  1395.  
  1396.     gdh = GetDeviceList();
  1397.     
  1398.     while (((*gdh)->gdRefNum != refnum) & (gdh != nil)) {
  1399.         gdh = GetNextDevice(gdh);
  1400.     }
  1401.     
  1402.     if (gdh != nil) {
  1403.     
  1404.         *gdhdl = gdh;    
  1405.         return ((*gdh)->gdPMap);
  1406.     }
  1407.     else {
  1408.         return (nil);
  1409.     }
  1410. }
  1411.  
  1412. long CheckAddressRange(Ptr baddr, Ptr ro364BaseAddr) {
  1413.  
  1414. long    error = 0;
  1415.  
  1416. /* The ro364 card has a maximum mapping area of x=1024 and y=511 */
  1417.  
  1418.  
  1419.     if ((baddr < ro364BaseAddr) || (baddr > (ro364BaseAddr+1024L*511L))) {
  1420.         error = noDMA;
  1421.     }
  1422.     return (error);
  1423. }
  1424.  
  1425. long CheckDestRect(short top, short left, short *h, short *v, Boolean *needsClip)
  1426. {
  1427. long    error = 0;
  1428.  
  1429.     *needsClip = FALSE;
  1430.     if ((top > 510) || (left > 1023) ) error = noDMA;
  1431.     
  1432.     if ((top + (*v)) > 510) {
  1433.         *v = 510 - top;
  1434.         if ((*v % 2) != 0) *v = *v + 1;                        /* special adjustment for RO364 */
  1435.         *needsClip = TRUE;
  1436.     }
  1437.     
  1438.     return (error);
  1439. }
  1440.  
  1441. /* Hopefully this will be added sometime to Movies Routines */
  1442. pascal void MatrixCopy( MatrixRecord *mfrom, MatrixRecord *mto)
  1443. {
  1444.     if (mfrom && mto) {
  1445.         (mto->matrix)[0][0] = (mfrom->matrix)[0][0];
  1446.         (mto->matrix)[0][1] = (mfrom->matrix)[0][1];
  1447.         (mto->matrix)[0][2] = (mfrom->matrix)[0][2];
  1448.         (mto->matrix)[1][0] = (mfrom->matrix)[1][0];
  1449.         (mto->matrix)[1][1] = (mfrom->matrix)[1][1];
  1450.         (mto->matrix)[1][2] = (mfrom->matrix)[1][2];
  1451.         (mto->matrix)[2][0] = (mfrom->matrix)[2][0];
  1452.         (mto->matrix)[2][1] = (mfrom->matrix)[2][1];
  1453.         (mto->matrix)[2][2] = (mfrom->matrix)[2][2];
  1454.         }
  1455. }
  1456.  
  1457. pascal void WhackCLUT(short refnum, GDHandle gdh) {
  1458.  
  1459. GDHandle     savegdh;
  1460. CTabHandle    aCTabHandle;
  1461. CntrlParam    pb;
  1462. long        error = noErr;
  1463. Size        s;
  1464.  
  1465.     savegdh = GetGDevice();
  1466.     SetGDevice(gdh);
  1467.  
  1468.     aCTabHandle = (CTabHandle) NewHandleClear ( sizeof(ColorSpec)*256 + 8); 
  1469.     (**aCTabHandle).ctSeed = GetCTSeed(); 
  1470.     (**aCTabHandle).ctSize = 255;     
  1471.  
  1472. /*    RO364 routine that gets a 332 color table doesn't work */
  1473.     Get332ColorTable(&(aCTabHandle)); 
  1474.     SetEntries(0,255,(**aCTabHandle).ctTable);
  1475.     
  1476.     DisposHandle((Handle)aCTabHandle);
  1477.     
  1478.     SetGDevice(savegdh);
  1479. }
  1480.  
  1481. pascal void Get332ColorTable(CTabHandle *aCTabHandle) {
  1482. short r,g,b,i;
  1483.  
  1484.     i = 0;
  1485.     for (r=0;r<=247;r+=31) {
  1486.         for (g=0;g<=247;g+=31) {
  1487.             for (b=0;b<=251;b+=63) {
  1488.                 (***aCTabHandle).ctTable[i].value = i;
  1489.                 (***aCTabHandle).ctTable[i].rgb.red = ~r << 8;
  1490.                 (***aCTabHandle).ctTable[i].rgb.green = ~g << 8;
  1491.                 (***aCTabHandle).ctTable[i].rgb.blue = ~b << 8;
  1492.                 i++;
  1493.                         
  1494.             }
  1495.         }    
  1496.     }        
  1497.  
  1498.  
  1499. }
  1500.  
  1501. short Pound364HoldOff( short value, GDHandle c364gdh )
  1502. {
  1503.     long    slotstart;
  1504.     long    oldlong;
  1505.     short    oldshort;
  1506.     long    *longaddr;
  1507.     short    *shortaddr;
  1508.     char    saveMode;
  1509.     
  1510.     slotstart = ((long)(**(**c364gdh).gdPMap).baseAddr) & 0xff000000;
  1511.     longaddr = (long *)(slotstart+0xfe6018);
  1512.     shortaddr = (short *)(slotstart+0xfe7004);
  1513.     
  1514. #if 1    
  1515.     saveMode = true;
  1516.     SwapMMUMode(&saveMode);
  1517.     oldlong = *longaddr;
  1518.     *longaddr = 3L;
  1519.     oldshort = *shortaddr;
  1520.     *shortaddr = value;
  1521.     *longaddr = oldlong;
  1522.     SwapMMUMode(&saveMode);
  1523.     return oldshort;
  1524. #else
  1525.     asm{
  1526.         moveq    #1, d0
  1527.         _SwapMMUMode
  1528.         move.b    d0, -(sp)
  1529.         
  1530.         move.l    longaddr,a0
  1531.         move.l    shortaddr,a1
  1532.         
  1533.         move.l    (a0), d0        ; get current page select
  1534.         move.l    #3, (a0)        ; set to our page
  1535.  
  1536.         move.w    value, (a1)        ; set the hold off
  1537.         move.l    d0, (a0)        ; restore page select
  1538.         
  1539.         move.b    (sp)+, d0
  1540.         _SwapMMUMode
  1541.     }
  1542.  
  1543. #endif
  1544.  
  1545. }
  1546.  
  1547. long    PoundSTVHoldOff( short value, short refnum) {
  1548.  
  1549. CntrlParam    pb;
  1550. long        error = noErr;
  1551.  
  1552.     pb.ioCRefNum = refnum;
  1553.     pb.csCode = 9016;
  1554.     pb.csParam[0] = value;
  1555.     error = PBControl((ParmBlkPtr)&pb,false);
  1556.     return (error);
  1557. }
  1558.  
  1559.  
  1560.  
  1561.  
  1562. Component RegisterRO364Component(void);
  1563. Component RegisterRO364Component(void)
  1564. {
  1565.     ComponentDescription foo;
  1566.  
  1567.       foo.componentType = 'vdig';
  1568.       foo.componentSubType = '    ';
  1569.       foo.componentManufacturer = 'rops';
  1570.       foo.componentFlags = 0;
  1571.       foo.componentFlagsMask = 0;
  1572.  
  1573.     return RegisterComponent(&foo, (void *)RO364Thing, 1, 0, 0, 0);
  1574. }
  1575.  
  1576.